package com.malou.server.base.acl;

import java.util.ArrayList;
import java.util.List;

public class My_Acl {

	List<My_Acl_Role> roles_id = new ArrayList<My_Acl_Role>();
	List<Integer> resources_id = new ArrayList<Integer>();
	public Integer user_id;
	public List<Integer> parents_id = new ArrayList<Integer>();
		
	Boolean [] user_resources;
	Boolean [][] roles_resources;
	
	public void addRole(My_Acl_Role rol){
		roles_id.add(rol);
	}
	
	public void add(Integer resource_id){
		resources_id.add(resource_id);
	}
	
	public void beforeAllow(){
		user_resources = new Boolean[resources_id.size()];
		roles_resources = new Boolean[roles_id.size()][resources_id.size()];
	}
	
	public void allow(Integer rol_id, Integer resource_id){
		int resource_index = getIndexResource(resource_id);
		int rol_index = getIndexRol(rol_id);
		roles_resources[rol_index][resource_index] = true;
	}
	
	public void deny(Integer rol_id, Integer resource_id){
		int resource_index = getIndexResource(resource_id);
		int rol_index = getIndexRol(rol_id);
		roles_resources[rol_index][resource_index] = false;
	}
	
	public void allow(Integer resource_id){
		int resource_index = getIndexResource(resource_id);
		user_resources[resource_index] = true;
	}
	
	public void deny(Integer resource_id){
		int resource_index = getIndexResource(resource_id);
		user_resources[resource_index] = false;
	}
	
	public boolean isAllowed(Integer rol_id, Integer resource_id){
		boolean retorno = false;
		Integer parent_id = null;
		int resource_index = getIndexResource(resource_id);		
		int rol_index = getIndexRol(rol_id);
		
		if(roles_resources[rol_index][resource_index] != null){
			if(roles_resources[rol_index][resource_index])
				retorno = true;
		}else{			
			parent_id = getParentId(rol_id); 
			if(parent_id != -1)
				if(isAllowed(parent_id, resource_id))
					retorno = true;
		}
		
		
		return retorno;
	}
	
	public boolean isAllowed(Integer resource_id){		
		boolean retorno = false;
		int resource_index = getIndexResource(resource_id);
		if(user_resources[resource_index] != null){
			if(user_resources[resource_index])
				retorno = true;
		}else if(parents_id != null){
			Integer parent_id = null;
			for(int i = 0; i < parents_id.size(); i++ ){
				parent_id = parents_id.get(i);
				if(isAllowed(parent_id, resource_id)){
					retorno = true;
					break;
				}
			}
		}
		return retorno;
	}
	
	private int getIndexResource(Integer resource_id){		
		return resources_id.indexOf(resource_id);
	}
	
	private int getIndexRol(Integer rol_id){
		My_Acl_Role acl_role;
		Integer index = null;
		for(int i = 0; i < roles_id.size(); i++){
			acl_role = roles_id.get(i);
			if(acl_role.rol_id == rol_id){				
				index = i;
				break;
			}
		}
		return index;
	}
	private Integer getParentId(Integer rol_id){
		My_Acl_Role acl_role;
		Integer parent_id = -1;
		for(int i = 0; i < roles_id.size(); i++){
			acl_role = roles_id.get(i);
			if(acl_role.rol_id == rol_id){
				if(acl_role.parent_id != null)
					parent_id = acl_role.parent_id;
				break;
			}
		}
		return parent_id;
	}
	
	public List<Integer> getAllRoles(){
		List<Integer> all = new ArrayList<Integer>();
		for(My_Acl_Role ar:roles_id){
			all.add(ar.rol_id);
		}
		return all;
	} 
	
	public static void main(String [] args){
		My_Acl my_acl= new My_Acl();
		my_acl.add(1);
		my_acl.add(2);
		my_acl.addRole(new My_Acl_Role(1));
		my_acl.addRole(new My_Acl_Role(2));
		my_acl.addRole(new My_Acl_Role(3, 1));
		my_acl.beforeAllow();
		
		my_acl.allow(1, 1);
		my_acl.allow(1, 2);
		my_acl.allow(2, 2);
		my_acl.deny(3, 2);
		
		//my_acl.user_id = 1;
		//my_acl.parents_id.add(2);
		//my_acl.parents_id.add(3);
		
		if(my_acl.isAllowed(3, 1))
			System.out.println("Permitido");
		else
			System.out.println("Denegado");
		/*Boolean [] arr = new Boolean[3];
		for(int i = 0; i < arr.length; i++){
			System.out.println(arr[i]);
		}*/
	}
		
}